home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 9 / FM Towns Free Software Collection 9.iso / t_os / game / break / test / test.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  18.6 KB  |  547 lines

  1. /* 画面回転処理 テストプログラム 1994年5月14日 */
  2.  
  3. #include <math.h>
  4. #include <stdio.h>
  5.  
  6. #define R 32   /* 赤 */
  7. #define G 1024 /* 緑 */
  8. #define B 1    /* 青 */
  9.  
  10. #define MAX_X 896   /* 仮想VRAMのX方向の大きさ(dot単位) */
  11. #define MAX_Y 896   /* 仮想VRAMのY方向の大きさ(dot単位) */
  12.  
  13. #define DSP_X 112   /* 表示画面のX方向の大きさ(dot単位) */
  14. #define DSP_Y 112   /* 表示画面のY方向の大きさ(dot単位) */
  15.  
  16. char gwork[1540];
  17. double RAD=3.141592/180; /* ラジアン */
  18. int deg;   /* 回転角 */
  19. short kvram[MAX_X][MAX_Y];
  20. unsigned int W_PAGE; /* レイア1の書き込みページ(0=(0,0) 0x20000=(0,128)) */
  21. unsigned int VRAM;   /* VRAMの先頭アドレス */
  22.  
  23. short tile[7][256]; /* 背景のキャラクタパターン */
  24.  
  25. int X=MAX_X/2;     /* 仮想VRAMの中心(X座標) */
  26. int Y=MAX_Y/2;     /* 仮想VRAMの中心(Y座標) */
  27.  
  28. /* 三角関数テーブル */
  29. int PC[72];  /* 余弦×0x1000×0x1000    (360°を72分割) */
  30. int MC[72];  /* 余弦×0x1000×(-0x1000) (360°を72分割) */
  31. int MS[72];  /* 正弦×0x1000×(-0x1000) (360°を72分割) */
  32.  
  33. /* roll2用オフセットテーブル */
  34. int XPC[72][DSP_X],YMS[72][DSP_Y],XMS[72][DSP_X],YMC[72][DSP_Y];
  35.  
  36. /* roll3用オフセットテーブル */
  37. int XOF[72][DSP_X],YOF[72][DSP_Y];
  38.  
  39. int MAP[56][56];  /* マップ */
  40.  
  41. int tx,ty;   /* 表示画面の回転中心に対応する仮想VRAMの座標 */
  42.  
  43.  
  44.  
  45. main()
  46.  
  47. {
  48.  int i,j;
  49.  
  50.  init_tri();  /* 三角関数テーブルの作成 */
  51.  init_tri2(); /* roll2用オフセットテーブルの作成 */
  52.  init_tri3(); /* roll3用オフセットテーブルの作成 */
  53.  
  54.  EGB_init( gwork, 1536 ) ;               /* BIOSの初期化 */
  55.  EGB_resolution( gwork, 0, 10 ) ;        /* ページ0の解像度設定(モード10) */
  56.  EGB_resolution( gwork, 1, 10 ) ;        /* ページ1の解像度設定(モード10) */
  57.  EGB_displayPage( gwork, 1, 3 ) ;        /* 表示ページの設定(両ページ) */
  58.  
  59.  EGB_writePage( gwork, 1 ) ;             /* 書き込みページを1に */
  60.  EGB_displayStart( gwork, 2, 4, 4 ) ;    /* 表示範囲の倍率設定(4X4) */
  61.  EGB_displayStart( gwork, 3, 128,240 ) ; /* 表示範囲の設定 */
  62.  EGB_displayStart( gwork, 0, 0, 0 ) ;    /* 表示開始位置 */
  63.  EGB_displayStart( gwork, 1, 0, 0 ) ;    /* 仮想画面中の位置 */
  64.  
  65.  EGB_writePage( gwork, 0 ) ;             /* 書き込みページを0に */
  66.  EGB_displayStart( gwork, 2, 2, 2 ) ;    /* 表示範囲の倍率設定(2X2) */
  67.  EGB_displayStart( gwork, 3, 320,240 ) ; /* 表示範囲の設定 */
  68.  EGB_displayStart( gwork, 0, 0, 0 ) ;    /* 表示開始位置 */
  69.  EGB_displayStart( gwork, 1, 0, 0 ) ;    /* 仮想画面中の位置 */
  70.  
  71.  EGB_fontStyle(gwork,1);      /* 太文字 */
  72.  EGB_textZoom(gwork,0,8,16);  /* ANKの拡大率 */
  73.  EGB_textZoom(gwork,1,16,16); /* 漢字の拡大率 */
  74.  EGB_color(gwork,0,0x7fff);   /* 文字色→白 */
  75.  
  76.  for (i=0;i<256;i++)
  77.   {
  78.    tile[0][i]=B*31;
  79.    tile[1][i]=R*31;
  80.    tile[2][i]=(R+B)*31;
  81.    tile[3][i]=G*31;
  82.    tile[4][i]=(G+B)*31;
  83.    tile[5][i]=(G+R)*31;
  84.    tile[6][i]=(G+R+B)*31;
  85.   };
  86.  
  87. /* マップの作成 */
  88.  for (j=0;j<56;j++) {for (i=0;i<56;i++) MAP[j][i]=rnd(6);};
  89.  
  90.  
  91.  /* 仮想VRAMの初期画面作成 */
  92.  for (j=0;j<56;j++)
  93.   {
  94.    for (i=0;i<56;i++) prtchr(kvram,i*16,j*16,tile[MAP[j][i]]);
  95.   };
  96.  
  97. /* roolのテスト */
  98.  init();
  99.  EGB_putSjis(gwork,240,20,"roll");
  100.  EGB_putSjis(gwork,240,52+16*1,"表示画面");
  101.  EGB_putSjis(gwork,240,52+16*2,"1点毎に");
  102.  EGB_putSjis(gwork,240,52+16*3,"対応する");
  103.  EGB_putSjis(gwork,240,52+16*4,"仮想");
  104.  EGB_putSjis(gwork,240,52+16*5,"VRAM");
  105.  EGB_putSjis(gwork,240,52+16*6,"アドレス");
  106.  EGB_putSjis(gwork,240,52+16*7,"を計算し");
  107.  EGB_putSjis(gwork,240,52+16*8,"ている。");
  108.  EGB_putSjis(gwork,240,240-16,"SELECTボタン");
  109.  EGB_putSjis(gwork,240,240,"Next Test");
  110.  while(1)
  111.   {
  112.    move(); /* 仮想VRAM中の表示位置の移動 */
  113.    roll(PC[deg],MC[deg],MS[deg],VRAM+W_PAGE,kvram[0],tx>>12,ty>>12,0,0,0,0);
  114.    page(W_PAGE>>10); W_PAGE=W_PAGE^0x20000; /* 改ページ */
  115.    if ((INPB(0x04d0) & 0x03)==0) break; /* SELECTボタン押下 -> 強制終了 */
  116.   };
  117.  while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  118.  
  119. /* roll2のテスト */
  120.  init();
  121.  EGB_putSjis(gwork,240,20,"roll2");
  122.  EGB_putSjis(gwork,240,28+16*1,"-56<X<56");
  123.  EGB_putSjis(gwork,240,28+16*2,"-56<Y<56");
  124.  EGB_putSjis(gwork,240,28+16*3,"の範囲で");
  125.  EGB_putSjis(gwork,240,28+16*4," X×Cosθ,");
  126.  EGB_putSjis(gwork,240,28+16*5,"-Y×Sinθ,");
  127.  EGB_putSjis(gwork,240,28+16*6,"-X×Sinθ,");
  128.  EGB_putSjis(gwork,240,28+16*7,"-Y×Cosθ");
  129.  EGB_putSjis(gwork,240,28+16*8,"をテーブル化");
  130.  EGB_putSjis(gwork,240,28+16*9,"これで");
  131.  EGB_putSjis(gwork,240,28+16*10,"仮想VRAM");
  132.  EGB_putSjis(gwork,240,28+16*11,"アドレス算出");
  133.  EGB_putSjis(gwork,240,240-16,"SELECTボタン");
  134.  EGB_putSjis(gwork,240,240,"Next Test");
  135.  while(1)
  136.   {
  137.    move(); /* 仮想VRAM中の表示位置の移動 */
  138.    roll2(&(XPC[deg][0]),&(YMS[deg][0]),&(XMS[deg][0]),&(YMC[deg][0]),VRAM+W_PAGE,kvram[0],tx>>12,ty>>12);
  139.    page(W_PAGE>>10); W_PAGE=W_PAGE^0x20000; /* 改ページ */
  140.    if ((INPB(0x04d0) & 0x03)==0) break; /* SELECTボタン押下 -> 強制終了 */
  141.   };
  142.  while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  143.  
  144. /* roll3のテスト */
  145.  init();
  146.  EGB_putSjis(gwork,240,20,"roll3");
  147.  EGB_putSjis(gwork,240,28+16*1,"-56<X<56");
  148.  EGB_putSjis(gwork,240,28+16*2,"-56<Y<56");
  149.  EGB_putSjis(gwork,240,28+16*3,"の範囲で");
  150.  EGB_putSjis(gwork,224,28+16*4," X(Cosθ-Sin");
  151.  EGB_putSjis(gwork,224,28+16*5,"  θ×MAX_X),");
  152.  EGB_putSjis(gwork,224,28+16*6,"-Y(Sinθ+Cos");
  153.  EGB_putSjis(gwork,224,28+16*7,"  θ×MAX_X)");
  154.  EGB_putSjis(gwork,240,28+16*8,"をテーブル化");
  155.  EGB_putSjis(gwork,240,28+16*9,"これで");
  156.  EGB_putSjis(gwork,240,28+16*10,"仮想VRAM");
  157.  EGB_putSjis(gwork,240,28+16*11,"アドレス算出");
  158.  EGB_putSjis(gwork,240,240-16,"SELECTボタン");
  159.  EGB_putSjis(gwork,240,240,"Test End");
  160.  while(1)
  161.   {
  162.    move(); /* 仮想VRAM中の表示位置の移動 */
  163.    roll3(XOF[deg],YOF[deg],VRAM+W_PAGE,kvram[0],tx>>12,ty>>12);
  164.    page(W_PAGE>>10); W_PAGE=W_PAGE^0x20000; /* 改ページ */
  165.    if ((INPB(0x04d0) & 0x03)==0) break; /* SELECTボタン押下 -> 強制終了 */
  166.   };
  167.  while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  168.  
  169.  screenterm(gwork); /* MS-DOSの画面モードに設定する。*/
  170.  
  171. };
  172.  
  173.  
  174. init()
  175.         /* テスト毎の初期化処理 */
  176. {
  177.  W_PAGE=0; /* レイア1の書き込みページ(0=(0,0) 0x20000=(0,128)) */
  178.  VRAM=g_loc(0,4)+0x40000;  /* VRAMの先頭アドレス */
  179.  deg=54;   /* 回転角 */
  180.  tx=MAX_X/2*0x1000; ty=MAX_Y/2*0x1000;   /* マイタンクの座標(中心) */
  181.  g_cls();
  182. };
  183.  
  184.  
  185. /* sqr(56^2+80^2)=97≒98 */
  186. #define LIM_MIN 98  /* X & Y の最小値 */
  187. #define LIM_MAX 797 /* X & Y の最大値(895-98) */
  188.  
  189. move()
  190.           /* 仮想VRAM中の表示位置の移動 */
  191. {
  192.  int p,wtx,wty;
  193.  int pc,mc,ms;
  194.  
  195.  p=INPB(0x04d0);
  196.  
  197. /* 
  198.  X=xcos-ysin Y=-xsin-ycos
  199.  0=xcos-ysin 1=-xsin-ycos -> y=-(Y+xsin)/cos  x=(X+ysin)/cos -> x=sin y=cos
  200.  0=xcos-ysin -1=-xsin-ycos -> y=(Y+xsin)/cos  x=(X+ysin)/cos -> x=-sin y=-cos
  201. */
  202.  
  203.  pc=PC[deg]*4; mc=MC[deg]*4; ms=MS[deg]*4;
  204.  wtx=tx; wty=ty;
  205.  if ((p & 0x01)==0) {ty=ty+pc; tx=tx-ms;}; /* パッド上 */
  206.  if ((p & 0x02)==0) {ty=ty+mc; tx=tx+ms;}; /* パッド下 */
  207.  
  208.  if ((p & 0x04)==0)     /* パッド左 */
  209.   {                                                /* Bボタン */
  210.    if ((p & 0x20)==0) {tx=tx-pc; ty=ty-ms;}        /* ONなら平行移動 */
  211.     else              {deg--; if (deg<0) deg=71;}; /* OFFなら回転 */
  212.   };
  213.  if ((p & 0x08)==0)     /* パッド右 */
  214.   {                                                /* Bボタン */
  215.    if ((p & 0x20)==0) {tx=tx-mc; ty=ty+ms;}        /* ONなら平行移動 */
  216.     else              {deg++; if (deg>71) deg=0;}; /* OFFなら回転 */
  217.   };
  218.  
  219.  /* 画面外かチェック */
  220.  if ( ((tx>>12)<LIM_MIN) || ((tx>>12)>LIM_MAX) ) tx=wtx;
  221.  if ( ((ty>>12)<LIM_MIN) || ((ty>>12)>LIM_MAX) ) ty=wty;
  222.  
  223. };
  224.  
  225.  
  226.  
  227. page(hed)
  228.                  /* レイア1のハードスクロール */
  229. int hed;         /* レイア1の画面表示開始位置 */
  230. {
  231.  asm("      pushl %edx");
  232.  asm("      movl 12(%esp),%eax");    /* hed */
  233.  asm("      andl $0xff,%eax");
  234.  asm("      roll $8,%eax");
  235.  asm("      pushl %eax");            /* FA1 */
  236.  asm("      movw $0x440,%dx");
  237.  asm("      movb $21,%al");
  238.  asm("      outb %al,%dx");
  239.  asm("      popl %eax");             /* FA1 */
  240.  asm("      movw $0x442,%dx");
  241.  asm("      outw %ax,%dx");
  242.  asm("      popl %edx");
  243.  
  244. }; 
  245.  
  246.  
  247. init_tri()
  248.               /* 三角関数テーブルの作成 */
  249. {
  250.  int i,j;
  251.  double c,s,r; /* 回転角 */
  252.  
  253.  for (i=0;i<72;i++)
  254.   {
  255.    r=(360/72*i)*RAD; c=cos(r)*0x1000; s=sin(r)*0x1000; /* ラジアンへの変換 */
  256.    PC[i]=c; MC[i]=-c; MS[i]=-s;
  257.   };
  258.  
  259. };
  260.  
  261.  
  262. roll(pc,mc,ms,vram,kvram,kx,ky,w0,w1,w2,w3)
  263. /*   44 48 52  56   60   64 68 72 76 80 84 */
  264.                                     /* 画面回転 1994年1月30日-2月8日 */
  265.  int pc;       /* cos×0x1000 */
  266.  int mc;       /* -cos×0x1000 */
  267.  int ms;       /* -sin×0x1000 */
  268.  int vram;     /* VRAM左上アドレス */
  269.  short *kvram; /* 仮想VRAM先頭アドレス -> 中心アドレス */
  270.  int kx,ky;    /* 仮想VRAM回転中心座標 -> X方向オフセット1,2*/
  271.  int w0,w1;    /* ワークエリア Y方向オフセット1,2 */
  272.  int w2,w3;    /* ワークエリア ループカウンタ */
  273. {
  274.  asm("        pushal");
  275.  
  276.  asm("        pushl %es");
  277.  asm("        pushl $0x0104");
  278.  asm("        popl %es");
  279.  
  280.  asm("        cld");                /* ストリング方向フラグ=0 */
  281.  asm("        movl 64(%esp),%ecx"); /* 中心 X座標 */
  282.  asm("        addl %ecx,%ecx");
  283.  asm("        movl 68(%esp),%eax"); /* 中心 Y座標 */
  284.  asm("        movl $1792,%ebx");    /* 仮想VRAM 1行の容量(MAX_X×2) */
  285.  asm("        mull %ebx");
  286.  asm("        addl %ecx,%eax");     /* 仮想VRAM 中心座標のオフセット */
  287.  asm("        addl %eax,60(%esp)"); /* +仮想VRAM先頭アドレス */
  288.  
  289.  asm("        movl $-56,%ebx");     /* 表示座標左上の点(-DSP_X/2) */
  290.  asm("        movl 52(%esp),%eax"); /* -sin */
  291.  asm("        imull %ebx");
  292.  asm("        movl %eax,68(%esp)"); /* X方向オフセット2 初期値 */
  293.  asm("        movl %eax,72(%esp)"); /* Y方向オフセット1 初期値 */
  294.  asm("        movl 44(%esp),%eax"); /* cos */
  295.  asm("        imull %ebx");
  296.  asm("        movl %eax,64(%esp)"); /* X方向オフセット1 初期値 */
  297.  asm("        movl 48(%esp),%eax"); /* -cos */
  298.  asm("        imull %ebx");
  299.  asm("        movl %eax,76(%esp)"); /* Y方向オフセット2 初期値 */
  300.  
  301.  asm("        movl $896,%ebx");     /* MAX_X */
  302.  asm("        movl $112,84(%esp)"); /* Y方向ループカウンタ(DSP_Y) */
  303.  asm("lpY:    movl $112,80(%esp)"); /* X方向ループカウンタ(DSP_X) */
  304.  asm("        movl 76(%esp),%eax"); /* Y方向オフセット2 */
  305.  asm("        sarl $12,%eax");
  306.  asm("        imull %ebx");         /* (Y方向オフセット2/0x1000)×MAX_X */
  307.  asm("        movl 72(%esp),%ebp"); /* Y方向オフセット1 */
  308.  asm("        sarl $12,%ebp");      /* (Y方向オフセット1)/0x1000 */
  309.  asm("        addl %eax,%ebp");     /* Y方向オフセット */
  310.  asm("        addl %ebp,%ebp");     /* ×2 */
  311.  asm("        addl 60(%esp),%ebp"); /* +仮想VRAM中心アドレス(基準点) */
  312.  asm("        movl 56(%esp),%edi"); /* 初期VRAMアドレス */
  313.  asm("        movl 64(%esp),%esi"); /* X方向オフセット1 */
  314.  asm("        movl 68(%esp),%ecx"); /* X方向オフセット2 */
  315.  
  316.  asm("lpX:    movl %ecx,%eax");     /* X方向オフセット2 */
  317.  asm("        sarl $12,%eax");
  318.  asm("        imull %ebx");         /* (X方向オフセット2/0x1000)×MAX_X) */
  319.  asm("        movl %esi,%edx");     /* X方向オフセット1 */
  320.  asm("        sarl $12,%edx");      /* (X方向オフセット1)/0x1000 */
  321.  asm("        addl %edx,%eax");     /* X方向オフセット */
  322.  asm("        movw %ss:(%ebp,%eax,2),%ax"); /* 仮想VRAM回転変換位置の色情報 */
  323.  asm("        stosw");                      /* 描画対象VRAMに転送しVRAM+2 */
  324.  asm("        addl 44(%esp),%esi"); /* X方向オフセット1+cos */
  325.  asm("        addl 52(%esp),%ecx"); /* X方向オフセット2+(-sin) */
  326.  asm("        decl 80(%esp)");      /* X方向ループカウンタ-1 */
  327.  asm("        jnz lpX");
  328.  
  329.  asm("        addl $0x400,56(%esp)"); /* VRAM+0x400 */
  330.  asm("        movl 52(%esp),%eax");
  331.  asm("        addl %eax,72(%esp)"); /* Y方向オフセット1+(-sin) */
  332.  asm("        movl 48(%esp),%eax");
  333.  asm("        addl %eax,76(%esp)"); /* Y方向オフセット2+(-cos) */
  334.  asm("        decl 84(%esp)");      /* Y方向ループカウンタ-1 */
  335.  asm("        jnz lpY");
  336.  
  337.  asm("        popl %es");
  338.  
  339.  asm("        popal");
  340.  
  341. };
  342.  
  343.  
  344. init_tri2()
  345.               /* roll2用オフセットテーブルの作成 */
  346. {
  347. /* X=xcos-ysin Y=-xsin-ycos */
  348.  int i,j,k;
  349.  
  350.  for (i=0;i<72;i++)
  351.   {
  352.    for (j=0;j<DSP_X;j++)
  353.     {
  354.      k=j-(DSP_X/2);
  355.      XPC[i][j]=((PC[i]*k)>>12)*2; YMS[i][j]=((MS[i]*k)>>12)*MAX_X*2;
  356.      XMS[i][j]=((MS[i]*k)>>12)*2; YMC[i][j]=((MC[i]*k)>>12)*MAX_X*2;
  357.     };
  358.   };
  359.  
  360. };
  361.  
  362.  
  363. /* X=xcos-ysin Y=-xsin-ycos*/
  364. roll2(xpc,yms,xms,ymc,vram,kvram,kx,ky)
  365. /*    44  48  52  56   60   64   68 72 */
  366.                                   /* 画面回転(高速版1) 1994年3月28日-3月29日 */
  367.  int *xpc;      /* cos×x(-56:56)×2 */
  368.  int *yms;      /* -sin×y(-56:56)×MAX_X×2 */
  369.  int *xms;      /* -sin×x(-56:56)×2 */
  370.  int *ymc;      /* -cos×y(-56:56)×MAX_X×2 */
  371.  int vram;     /* VRAM左上アドレス */
  372.  short *kvram; /* 仮想VRAM先頭アドレス -> 中心アドレス */
  373.  int kx,ky;    /* 仮想VRAM回転中心座標 -> X方向オフセット1,2*/
  374. {
  375.  asm("        pushal");
  376.  
  377.  asm("        pushl %es");
  378.  asm("        pushl $0x0104");
  379.  asm("        popl %es");
  380.  
  381.  asm("        cld");                /* ストリング方向フラグ=0 */
  382.  asm("        movl 68(%esp),%ecx"); /* 中心 X座標 */
  383.  asm("        addl %ecx,%ecx");
  384.  asm("        movl 72(%esp),%eax"); /* 中心 Y座標 */
  385.  asm("        movl $1792,%ebx");    /* 仮想VRAM 1行の容量(MAX_X×2) */
  386.  asm("        mull %ebx");
  387.  asm("        addl %ecx,%eax");     /* 仮想VRAM 中心座標のオフセット */
  388.  asm("        addl %eax,64(%esp)"); /* +仮想VRAM先頭アドレス=>中心アドレス */
  389.  
  390.  asm("        movl $0,72(%esp)"); /* Y方向オフセット(0:DSP_Y) */
  391.  asm("lpY2:   movl 64(%esp),%edx"); /* 仮想VRAM中心アドレス */
  392.  asm("        movl 72(%esp),%ebx"); /* Y方向オフセット */
  393.  asm("        movl 52(%esp),%eax"); /* XMS先頭アドレス */
  394.  asm("        addl %ss:(%eax,%ebx,4),%edx"); /* kvram(中心)+xms */
  395.  asm("        movl 56(%esp),%eax"); /* YMC先頭アドレス */
  396.  asm("        addl %ss:(%eax,%ebx,4),%edx"); /* kvram(中心)+xms+ymc */
  397.  asm("        movl 60(%esp),%edi"); /* VRAM先頭アドレス */
  398.  asm("        xorl %ebx,%ebx");     /* X方向オフセット */
  399.  
  400.  asm("lpX2:   movl 44(%esp),%eax"); /* XPC先頭アドレス */
  401.  asm("        movl %ss:(%eax,%ebx,4),%esi"); /* xpc */
  402.  asm("        movl 48(%esp),%eax"); /* YMS先頭アドレス */
  403.  asm("        addl %ss:(%eax,%ebx,4),%esi"); /* xpc+yms */
  404.  asm("        movw %ss:(%edx,%esi),%ax"); /* 仮想VRAM回転変換位置の色情報 */
  405.  asm("        stosw");                    /* 描画対象VRAMに転送しVRAM+2 */
  406.  asm("        incl %ebx");      /* X方向オフセット+1 */
  407.  asm("        cmpl $112,%ebx"); /* DSP_X */
  408.  asm("        jnz lpX2");
  409.  
  410.  asm("        addl $0x0400,60(%esp)"); /* VRAMアドレス+0x400 */
  411.  asm("        incl 72(%esp)");      /* Y方向オフセット+1 */
  412.  asm("        cmpl $112,72(%esp)"); /* DSP_Y */
  413.  asm("        jnz lpY2");
  414.  
  415.  asm("        popl %es");
  416.  
  417.  asm("        popal");
  418.  
  419. };
  420.  
  421.  
  422. init_tri3()
  423.               /* roll3用オフセットテーブルの作成 */
  424. {
  425. /* X=xcos-ysin Y=-xsin-ycos */
  426.  int i,j,k;
  427.  
  428.  for (i=0;i<72;i++)
  429.   {
  430.    for (j=0;j<DSP_X;j++)
  431.     {
  432.      k=j-(DSP_X/2);
  433.      XOF[i][j]=(((PC[i]*k)>>12)+((MS[i]*k)>>12)*MAX_X)*2;
  434.      YOF[i][j]=(((MS[i]*k)>>12)+((MC[i]*k)>>12)*MAX_X)*2;
  435.     };
  436.   };
  437.  
  438. };
  439.  
  440.  
  441. roll3(xof,yof,vram,kvram,kx,ky)
  442. /*    44  48   52   56   60 64 */
  443.                                  /* 画面回転(高速版2) 1994年3月29日 */
  444. /* X=xcos-ysin Y=-xsin-ycos*/
  445.  int *xof;      /* (cos×x(-56:56)-sin×y(-56:56)×MAX_X)×2 */
  446.  int *yof;      /* (-sin×x(-56:56)-cos×y(-56:56)×MAX_X)×2 */
  447.  int vram;     /* VRAM左上アドレス */
  448.  short *kvram; /* 仮想VRAM先頭アドレス -> 中心アドレス */
  449.  int kx,ky;    /* 仮想VRAM回転中心座標 -> X方向オフセット1,2*/
  450. {
  451.  asm("        pushal");
  452.  
  453.  asm("        pushl %es");
  454.  asm("        pushl $0x0104");
  455.  asm("        popl %es");
  456.  
  457.  asm("        cld");                /* ストリング方向フラグ=0 */
  458.  asm("        movl 64(%esp),%eax"); /* 中心 Y座標 */
  459.  asm("        movl $896,%ebx");     /* MAX_X */
  460.  asm("        mull %ebx");
  461.  asm("        addl 60(%esp),%eax"); /* 中心 X座標+中心 Y座標×MAX_X */
  462.  asm("        addl %eax,%eax");     /* ×2(仮想VRAM 中心座標のオフセット) */
  463.  asm("        addl %eax,56(%esp)"); /* +仮想VRAM先頭アドレス=>中心アドレス */
  464.  
  465.  asm("        movl 44(%esp),%ebp"); /* XOF先頭アドレス */
  466.  asm("        xorl %ecx,%ecx");     /* Y方向オフセット(0:DSP_Y) */
  467.  asm("lpY3:   movl 56(%esp),%edx"); /* 仮想VRAM中心アドレス */
  468.  asm("        movl 48(%esp),%eax"); /* YOF先頭アドレス */
  469.  asm("        addl %ss:(%eax,%ecx,4),%edx"); /* kvram(中心)+YOF */
  470.  asm("        movl 52(%esp),%edi"); /* VRAM先頭アドレス */
  471.  asm("        xorl %ebx,%ebx");     /* X方向オフセット */
  472.  
  473.  asm("lpX3:   movl (%ebp,%ebx,4),%esi"); /* XOF */
  474.  asm("        movw %ss:(%edx,%esi),%ax"); /* 仮想VRAM回転変換位置の色情報 */
  475.  asm("        stosw");                    /* 描画対象VRAMに転送しVRAM+2 */
  476.  asm("        incl %ebx");      /* X方向オフセット+1 */
  477.  asm("        cmpl $112,%ebx"); /* DSP_X */
  478.  asm("        jnz lpX3");
  479.  
  480.  asm("        addl $0x0400,52(%esp)"); /* VRAMアドレス+0x400 */
  481.  asm("        incl %ecx");      /* Y方向オフセット+1 */
  482.  asm("        cmpl $112,%ecx"); /* DSP_Y */
  483.  asm("        jnz lpY3");
  484.  
  485.  asm("        popl %es");
  486.  
  487.  asm("        popal");
  488.  
  489. };
  490.  
  491.  
  492.  
  493.  
  494. prtchr(kvram,x,y,chr)
  495.                                     /* パターン転送 1994年2月9日 */
  496.  short *kvram; /* 仮想VRAM先頭アドレス */
  497.  int x,y;      /* 転送座標左上 */
  498.  short *chr;   /* キャラクタ先頭アドレス */
  499. {
  500.  asm("        pushal");
  501.  
  502.  asm("        pushl %es");
  503.  asm("        pushl %ss");
  504.  asm("        popl %es");
  505.  asm("        pushl %ss");
  506.  asm("        popl %ds");
  507.  
  508.  asm("        cld");                /* ストリング方向フラグ=0 */
  509.  asm("        movl 52(%esp),%eax"); /* 転送先 Y座標 */
  510.  asm("        movl $896,%ebx");
  511.  asm("        mull %ebx");          /* ×MAX_X */
  512.  asm("        addl 48(%esp),%eax"); /* 転送先 X座標 */
  513.  asm("        addl %eax,%eax");     /* ×2 */
  514.  asm("        addl 44(%esp),%eax"); /* 仮想VRAM描画開始アドレス */
  515.  asm("        movl %eax,%edi");
  516.  
  517.  asm("        movl 56(%esp),%esi"); /* キャラクタ先頭アドレス */
  518.  asm("        movl $16,%ebx");      /* Y方向ループカウンタ */
  519.  asm("LY:     movl $16,%ecx");      /* X方向ループカウンタ */
  520.  asm("LX:     lodsw"); /* キャラクタ -> ax & キャラクタアドレス+2 */
  521.  asm("        orw %ax,%ax");
  522.  asm("        jz skip");             /* キャラクタがNULL dotなら転送しない */
  523.  asm("        stosw"); /* ax -> 仮想VRAM & 仮想VRAM描画アドレス+2 */
  524.  asm("        loop LX");
  525.  asm("        addl $1760,%edi");    /* 仮想VRAM描画アドレス+(MAX_X-16)×2 */
  526.  asm("        decl %ebx");
  527.  asm("        jnz LY");
  528.  
  529.  asm("        popl %es");
  530.  
  531.  asm("        popal");
  532.  
  533.  asm("        leave");
  534.  asm("        ret");
  535.  
  536.  asm("skip:   addl $2,%edi");        /* 仮想VRAM描画アドレス+2 */
  537.  asm("        loop LX");
  538.  asm("        addl $1760,%edi");    /* 仮想VRAM描画アドレス+(MAX_X-16)×2 */
  539.  asm("        decl %ebx");
  540.  asm("        jnz LY");
  541.  
  542.  asm("        popl %es");
  543.  
  544.  asm("        popal");
  545.  
  546. };
  547.